package com.example.shutdown_v1.controller;

import com.example.shutdown_v1.entity.Gateway;
import com.example.shutdown_v1.entity.Sensor;
import com.example.shutdown_v1.entity.Shop;
import com.example.shutdown_v1.repository.GatewayRepository;
import com.example.shutdown_v1.repository.SensorRepository;
import com.example.shutdown_v1.repository.ShopRepository;
import com.example.shutdown_v1.service.RedisSensorDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 实时状态查询API
 * 从Redis获取传感器实时状态（而不是MySQL）
 */
@Slf4j
@RestController
@RequestMapping("/api/real-time")
@CrossOrigin(originPatterns = "*", allowCredentials = "false")
@RequiredArgsConstructor
public class RealTimeStatusController {

    private final SensorRepository sensorRepository;
    private final GatewayRepository gatewayRepository;
    private final ShopRepository shopRepository;
    private final RedisTemplate<String, Object> redisTemplate;
    
    @Autowired(required = false)
    private RedisSensorDataService redisSensorDataService;

    /**
     * 获取所有传感器的实时状态（从Redis）
     * @return 传感器列表及其实时状态
     */
    @GetMapping("/sensors")
    public ResponseEntity<?> getAllSensorsRealTimeStatus() {
        try {
            // 1. 从MySQL获取所有传感器基本信息
            List<Sensor> sensors = sensorRepository.findAll();
            
            if (redisSensorDataService == null) {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "Redis未启用，无法获取实时状态"
                ));
            }
            
            // 2. 获取所有门店信息
            Map<Long, Shop> shopMap = shopRepository.findAll().stream()
                .collect(Collectors.toMap(Shop::getId, s -> s, (a, b) -> a));
            
            // 3. 获取所有网关信息(通过shopId映射)，过滤掉shopId为null的
            Map<Long, Gateway> gatewayMap = gatewayRepository.findAll().stream()
                .filter(g -> g.getShopId() != null)  // 过滤掉shopId为null的网关，避免空指针
                .collect(Collectors.toMap(Gateway::getShopId, g -> g, (a, b) -> a));
            
            // 4. 从Redis获取每个传感器的实时状态
            List<Map<String, Object>> sensorStatusList = sensors.stream()
                .map(sensor -> {
                    Map<String, Object> sensorInfo = new HashMap<>();
                    sensorInfo.put("sensorId", sensor.getSensorId());
                    sensorInfo.put("shopId", sensor.getShopId());
                    sensorInfo.put("installPosition", sensor.getInstallPosition());
                    sensorInfo.put("installPositionName", sensor.getInstallPositionName());
                    sensorInfo.put("sensorModel", sensor.getSensorModel());
                    sensorInfo.put("lastOnlineTime", sensor.getLastOnlineTime());
                    
                    // 是否启用多圈检测：0=只判断角度（B类杠杆开关），1=角度+圈数（A类多圈开关）
                    sensorInfo.put("useMultiTurnDetection", sensor.getUseMultiTurnDetection());
                    
                    // 添加网关信息(通过店铺ID查询)
                    if (sensor.getShopId() != null && gatewayMap.containsKey(sensor.getShopId())) {
                        Gateway gateway = gatewayMap.get(sensor.getShopId());
                        sensorInfo.put("gatewayMac", gateway.getGatewayMac());
                        sensorInfo.put("signalStrength", gateway.getSignalStrength());
                    } else {
                        sensorInfo.put("gatewayMac", null);
                        sensorInfo.put("signalStrength", null);
                    }
                    
                    // 从Redis获取实时状态（使用小写传感器ID）
                    String sensorIdLowerCase = sensor.getSensorId().toLowerCase();
                    Map<String, Object> redisStatus = redisSensorDataService.getSensorStatus(sensorIdLowerCase);
                    
                    // 判断在线状态：优先使用Redis数据，如果Redis没有数据则使用数据库
                    boolean isOnline = false;
                    if (redisStatus.containsKey("isOnline")) {
                        // Redis有数据，使用Redis状态
                        isOnline = (Boolean) redisStatus.getOrDefault("isOnline", false);
                    } else {
                        // Redis没有数据，使用数据库状态
                        isOnline = !(sensor.getIsOffline() != null && sensor.getIsOffline());
                    }
                    boolean isOffline = !isOnline;
                    
                    sensorInfo.put("state", redisStatus.getOrDefault("state", "unknown"));
                    sensorInfo.put("compositeAngle", redisStatus.get("compositeAngle"));
                    sensorInfo.put("confidence", redisStatus.get("confidence"));
                    sensorInfo.put("isOnline", isOnline);
                    sensorInfo.put("isOffline", isOffline);  // 添加isOffline字段供前端使用
                    sensorInfo.put("currentState", redisStatus.getOrDefault("state", "unknown"));
                    
                    // 综合圈数（仅在启用多圈检测时显示）
                    Integer useMultiTurn = sensor.getUseMultiTurnDetection();
                    if (useMultiTurn != null && useMultiTurn == 1) {
                        sensorInfo.put("compositeRotationCount", redisStatus.get("compositeRotationCount"));
                    } else {
                        sensorInfo.put("compositeRotationCount", null);  // 未启用时返回null
                    }
                    
                    // RSSI信号强度
                    sensorInfo.put("rssi", redisStatus.get("rssi"));
                    
                    // 如果Redis中有lastUpdateTime，转换为可读时间
                    Object lastUpdateTime = redisStatus.get("lastUpdateTime");
                    if (lastUpdateTime != null) {
                        sensorInfo.put("lastUpdateTime", lastUpdateTime);
                    }
                    
                    return sensorInfo;
                })
                .collect(Collectors.toList());
            
            // 5. 按门店分组，并附加门店详细信息
            Map<Long, Map<String, Object>> groupedByShopWithInfo = new HashMap<>();
            sensorStatusList.stream()
                .filter(s -> s.get("shopId") != null)
                .forEach(s -> {
                    Long shopId = (Long) s.get("shopId");
                    groupedByShopWithInfo.putIfAbsent(shopId, new HashMap<>());
                    Map<String, Object> shopData = groupedByShopWithInfo.get(shopId);
                    
                    // 添加门店信息（只添加一次）
                    if (!shopData.containsKey("shopInfo")) {
                        if (shopMap.containsKey(shopId)) {
                            Shop shop = shopMap.get(shopId);
                            Map<String, Object> shopInfo = new HashMap<>();
                            shopInfo.put("id", shop.getId());
                            shopInfo.put("name", shop.getName());
                            shopInfo.put("location", shop.getLocation());
                            shopInfo.put("zoneNumber", shop.getZoneNumber());
                            shopInfo.put("shopType", shop.getShopType());
                            shopInfo.put("shopCategory", shop.getShopCategory());
                            shopInfo.put("contactPhone", shop.getContactPhone());
                            shopInfo.put("responsiblePerson", shop.getResponsiblePerson());
                            shopData.put("shopInfo", shopInfo);
                        }
                        shopData.put("sensors", new ArrayList<Map<String, Object>>());
                    }
                    
                    // 添加传感器到该门店
                    @SuppressWarnings("unchecked")
                    List<Map<String, Object>> shopSensors = (List<Map<String, Object>>) shopData.get("sensors");
                    if (shopSensors != null) {
                        shopSensors.add(s);
                    }
                });
            
            // 6. 未分配门店的传感器
            List<Map<String, Object>> unassignedSensors = sensorStatusList.stream()
                .filter(s -> s.get("shopId") == null)
                .collect(Collectors.toList());
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("groupedByShop", groupedByShopWithInfo);
            response.put("unassignedSensors", unassignedSensors);
            response.put("totalCount", sensorStatusList.size());
            response.put("onlineCount", sensorStatusList.stream().filter(s -> (Boolean) s.getOrDefault("isOnline", false)).count());
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取实时状态失败", e);
            return ResponseEntity.ok(Map.of(
                "success", false,
                "message", "获取实时状态失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 获取所有门店及其传感器、网关的实时状态（新版API for新UI）
     * @return {shops: [{shopInfo, gateway, sensors}]}
     */
    @GetMapping("/status")
    public ResponseEntity<?> getAllStatus() {
        try {
            if (redisSensorDataService == null) {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "Redis未启用，无法获取实时状态"
                ));
            }
            
            // 1. 获取所有门店
            List<Shop> shops = shopRepository.findAll();
            List<Map<String, Object>> shopsData = new ArrayList<>();
            
            // 2. 获取所有传感器
            List<Sensor> allSensors = sensorRepository.findAll();
            
            // 3. 获取所有网关
            Map<Long, Gateway> gatewayMap = gatewayRepository.findAll().stream()
                .collect(Collectors.toMap(Gateway::getShopId, g -> g, (a, b) -> a));
            
            // 4. 按门店分组处理
            for (Shop shop : shops) {
                Map<String, Object> shopData = new HashMap<>();
                
                // 4.1 门店信息
                Map<String, Object> shopInfo = new HashMap<>();
                shopInfo.put("id", shop.getId());
                shopInfo.put("name", shop.getName());
                shopInfo.put("location", shop.getLocation());
                shopInfo.put("zoneNumber", shop.getZoneNumber());
                shopInfo.put("shopType", shop.getShopType());
                shopInfo.put("shopCategory", shop.getShopCategory());
                shopInfo.put("contactPhone", shop.getContactPhone());
                shopInfo.put("responsiblePerson", shop.getResponsiblePerson());
                // 断路器相关字段已下线：不再返回 breakerId/powerStatus/lastPower*
                
                // 断路器已停用：不再读取断路器信号强度
                
                shopData.put("shopInfo", shopInfo);
                
                // 4.2 网关信息
                Gateway gateway = gatewayMap.get(shop.getId());
                if (gateway != null) {
                    Map<String, Object> gatewayInfo = new HashMap<>();
                    gatewayInfo.put("id", gateway.getId());
                    gatewayInfo.put("gatewayMac", gateway.getGatewayMac());
                    gatewayInfo.put("signalStrength", gateway.getSignalStrength());
                    gatewayInfo.put("status", gateway.getStatus());
                    gatewayInfo.put("startTime", gateway.getStartTime());
                    gatewayInfo.put("lastMessageTime", gateway.getLastMessageTime());
                    shopData.put("gateway", gatewayInfo);
                } else {
                    shopData.put("gateway", null);
                }
                
                // 4.3 该门店的传感器列表
                List<Map<String, Object>> sensors = allSensors.stream()
                    .filter(sensor -> shop.getId().equals(sensor.getShopId()))
                    .map(sensor -> {
                        Map<String, Object> sensorInfo = new HashMap<>();
                        sensorInfo.put("sensorId", sensor.getSensorId());
                        sensorInfo.put("installPosition", sensor.getInstallPosition());
                        sensorInfo.put("installPositionName", sensor.getInstallPositionName());
                        sensorInfo.put("sensorModel", sensor.getSensorModel());
                        sensorInfo.put("useMultiTurnDetection", sensor.getUseMultiTurnDetection());
                        
                        // 从Redis获取实时状态（使用小写传感器ID）
                        try {
                            String sensorIdLowerCase = sensor.getSensorId().toLowerCase();
                            Map<String, Object> redisStatus = redisSensorDataService.getSensorStatus(sensorIdLowerCase);
                            sensorInfo.putAll(redisStatus);
                        } catch (Exception e) {
                            log.warn("获取传感器{}实时状态失败: {}", sensor.getSensorId(), e.getMessage());
                            sensorInfo.put("isOnline", false);
                            sensorInfo.put("state", "unknown");
                        }
                        
                        // 添加网关MAC（不添加信号强度，因为已从Redis的RSSI字段获取）
                        if (gateway != null) {
                            sensorInfo.put("gatewayMac", gateway.getGatewayMac());
                            //  signalStrength已从Redis的rssi字段获取，这里不再覆盖
                        }
                        
                        return sensorInfo;
                    })
                    .collect(Collectors.toList());
                
                // 断路器已停用：不再将断路器作为设备加入列表
                
                shopData.put("sensors", sensors);
                shopsData.add(shopData);
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("shops", shopsData);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取实时状态失败", e);
            return ResponseEntity.ok(Map.of(
                "success", false,
                "message", "获取实时状态失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 获取单个传感器的实时状态
     * @param sensorId 传感器ID
     * @return 实时状态
     */
    @GetMapping("/sensor/{sensorId}")
    public ResponseEntity<?> getSensorRealTimeStatus(@PathVariable String sensorId) {
        try {
            if (redisSensorDataService == null) {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "Redis未启用"
                ));
            }
            
            // 从Redis获取状态（使用小写传感器ID）
            String sensorIdLowerCase = sensorId.toLowerCase();
            Map<String, Object> status = redisSensorDataService.getSensorStatus(sensorIdLowerCase);
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("sensorId", sensorId);
            response.putAll(status);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取传感器{}实时状态失败", sensorId, e);
            return ResponseEntity.ok(Map.of(
                "success", false,
                "message", "获取失败: " + e.getMessage()
            ));
        }
    }
}

